项目功能实现:评论框插入表情

您所在的位置:网站首页 评论 表情包 项目功能实现:评论框插入表情

项目功能实现:评论框插入表情

2024-06-29 19:17:14| 来源: 网络整理| 查看: 265

「本文已参与低调务实优秀中国好青年前端社群的写作活动」

问题

一个 React 项目(用的函数组件)需要支持可以回复表情的评论,看到这个需求,相信读者们能想到好几种解决方案,比如使用成熟的富文本编辑器、使用第三方表情组件库、自己封装组件......

考虑到开发成本不能太高、评论组件可以复用、需求只是支持表情即可,因此笔者选择了第二种解决方案,也就是说,要去技术调研以选择合适的第三方库。

技术选型

GitHub 上有很多开源的表情库,对比了一下,个人觉得 emoji-mart 是最好的一个,原因:

star 数达到了 5.4 k ; 使用文档清晰易懂,支持中文; 作者持续维护,可以看到上一次的 commit 时间是 5天 前; UI 设计高级,符合笔者审美。

到这里,就确定了技术选型(出来吧 emoji-mart 就决定是你了hhh)

实践 安装表情组件库

我们首先使用 npm install --save emoji-mart @emoji-mart/data 将库安装下来。

生成容器组件

然后把 demo 跑起来,这里新建了一个 EmojiPicker.js 文件,用于生成容器组件,其代码如下:

import React, { useEffect, useRef } from 'react'; import data from '@emoji-mart/data'; import { Picker } from 'emoji-mart'; function EmojiPicker(props) { const ref = useRef(); useEffect(() => { new Picker({ ...props, data, ref }); }, []); return ; } export default EmojiPicker;

容器组件生成之后,就可以在其他地方使用,并调用它的 API 。在上面这段代码中,是不能在 div 中调用诸如 onEmojiSelect 之类的 API 的,因为此时容器组件还没生成,div 还仅仅只是 div 而已,这也是为什么要新建一个 EmojiPicker.js 的原因。

调用容器组件

在评论框处调用 EmojiPicker ,即可在页面中看到效果了。

searchEmoji(emoji)} /> 这里只展示与表情组件库有关联的输入框,其他相关组件的布局这里就不一一写出来了,请读者自由发挥 onChatContentChange(e.target.value)} // 文本值发生改变时的回调 />

到这里,我们离成功实现评论功能迈进了一小步,但还不够,可以看到上面代码有三个动态数据,分别是一个 chatContent 字段、onChatContentChange 函数和 searchEmoji 函数,我们继续往(写)下(bug)。

封装函数 第一版

在输入框进行键盘输入和表情插入,我们可以想到这样的逻辑:

①键盘输入时直接调用输入框的 onChange API 更新文本值 chatContent 即可 ②插入表情时调用组件库的 onEmojiSelect API 获取到要插入的表情,拼接到 chatContent 后面

于是有了下面的代码:

const [chatContent, setChatContent] = useState(''); // ①输入框文本值发生改变的回调函数 const onChatContentChange = (value) => { setChatContent(value); }; // ②选中表情的回调函数 const searchEmoji = (emoji) => { // 考虑到在一开始就插入表情的情况 const newChatContent = chatContent.length > 0 ? chatContent + emoji.native : emoji.native; setChatContent(newChatContent); };

然而这版的代码是有 bug 的,假如先输入“你好”,再插入表情,预计结果应该是“你好【表情】”,然而实际结果是“【表情】”,如图所示: 输入“你好” 在“你好”后输入表情

为什么会这样呢?这是因为 chatContent.length 为 0 ,自然就被赋值为 emoji.native 了。那么,在 @飞哥 的提点下,用 tempTextAreaData 全局字段存储输入框的文本值,这样就可以在页面更新的时候依然也能拿到最新的文本值,因此代码变成这样:

+ let tempTextAreaData = ''; const [chatContent, setChatContent] = useState(''); // ①输入框文本值发生改变的回调函数 const onChatContentChange = (value) => { setChatContent(value); + tempTextAreaData = value; }; // ②选中表情的回调函数 const searchEmoji = (emoji, event) => { // 考虑到在一开始就插入表情的情况 - const newChatContent = chatContent.length > 0 ? chatContent + emoji.native : emoji.native; + const newChatContent = tempTextAreaData.length > 0 ? tempTextAreaData + emoji.native : emoji.native; + tempTextAreaData = newChatContent; setChatContent(newChatContent); };

来看看效果:

输入“你好” 在“你好”后输入表情

第二版

我们完成了第一版的代码,实现了在输入框文本值后面插入表情,但有一个缺陷:不能在文本中间插入表情,因此我们的代码逻辑需要进一步完善。

笔者的思考方向是这样的:当光标移动到文本中间时,获取这个光标的位置,截断光标之前和光标之后的字符,将表情拼接到两者之间。

onChatContentChange 函数比较简单,第一版已经搞定了,现在我们完善 searchEmoji 函数:

// 由于在光标中间拼接表情稍微复杂了一点,这里单独抽成 insertAtCursor 函数,tempTextAreaData 的更新也将在 insertAtCursor 中完成 const searchEmoji = (emoji) => { let dom = document.getElementById('textarea'); // 获取输入框的节点对象 insertAtCursor(dom, emoji.native); // 将表情插入到光标后面 };

insertAtCursor 函数:

const insertAtCursor = (myField, myValue) => { if (document.selection) { //IE support myField.focus(); const sel = document.selection.createRange(); sel.text = myValue; sel.select(); } else if (myField.selectionStart || myField.selectionStart == '0') { //MOZILLA/NETSCAPE support const startPos = myField.selectionStart; const endPos = myField.selectionEnd; const beforeValue = myField.value.substring(0, startPos); const afterValue = myField.value.substring(endPos, myField.value.length); tempTextAreaData = beforeValue + myValue + afterValue; setChatContent(tempTextAreaData); myField.selectionStart = startPos + myValue.length; myField.selectionEnd = startPos + myValue.length; myField.focus(); } else { tempTextAreaData += myValue; setChatContent(tempTextAreaData); myField.focus(); } }

这样一来,就可以在文本中插入表情了,效果如图:

输入一段文字

文本中插入表情

将选取替换成表情

思考

在第二版代码完成之后,这个项目需求就完成了,当然,这样的实现是基于这个评论功能只需要支持表情就好,对于图片的插入、上传等是不支持的,如果确实需要支持图片的话,其实可以考虑富文本编辑器,工具栏简洁一点,支持图片和表情,也就可以了。

关于富文本编辑器的技术选型,可以参考这篇文章:前端开发常用的10款富文本编辑器。

希望读者们能多多支持这个项目: onepiece-web(star 一下不亏的 ^_^) 以上就是全部内容了,希望对大家有所帮助~



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭